Define new notify_remote_via_irq() interface which is a
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 29 Sep 2005 14:49:54 +0000 (15:49 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 29 Sep 2005 14:49:54 +0000 (15:49 +0100)
safe version for drivers to use that is aware of
save/restore. Post-restore notifications are silently
dropped, in the expectation that xenbus will eventually
get round to telling the driver it needs to reconnect.

Signed-off-by: Keir Fraser <keir@xensource.com>
13 files changed:
linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
linux-2.6-xen-sparse/include/asm-xen/evtchn.h

index 5e5ccc8d19b1f0c7a9ea6e337e67abf7ebb42adc..483d3ea29dedc97a02e8caf1df4d1042a05b0c48 100644 (file)
@@ -133,7 +133,7 @@ static inline void __send_IPI_one(unsigned int cpu, int vector)
 {
        int evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
        BUG_ON(evtchn < 0);
-       notify_via_evtchn(evtchn);
+       notify_remote_via_evtchn(evtchn);
 }
 
 void __send_IPI_shortcut(unsigned int shortcut, int vector)
index 32294c7bcda6265a573ec9f1029f7386076595b6..cef53c81ccbe3ced24d7a906d3e1664347cefc37 100644 (file)
@@ -622,6 +622,14 @@ void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
        synch_set_bit(evtchn, &s->evtchn_pending[0]);
 }
 
+void notify_remote_via_irq(int irq)
+{
+       int evtchn = irq_to_evtchn[irq];
+
+       if (VALID_EVTCHN(evtchn))
+               notify_remote_via_evtchn(evtchn);
+}
+
 void irq_resume(void)
 {
        evtchn_op_t op;
index 807f0fd9b4b0fbd9c78f3df1d6e08faebff5dbdd..faa65e712e002064edfbb42a3d0f29584f3727e7 100644 (file)
@@ -33,7 +33,7 @@ static inline void __send_IPI_one(unsigned int cpu, int vector)
 {
        int evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
        BUG_ON(evtchn < 0);
-       notify_via_evtchn(evtchn);
+       notify_remote_via_evtchn(evtchn);
 }
 
 void xen_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int dest)
index 134c8d06c39c64a442661094444ded49b3f4d8b9..c7693422551e8d7628d2755badcadf74597d3e73 100644 (file)
@@ -481,7 +481,7 @@ static void make_response(blkif_t *blkif, unsigned long id,
        spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
 
        /* Kick the relevant domain. */
-       notify_via_evtchn(blkif->evtchn);
+       notify_remote_via_irq(blkif->irq);
 }
 
 void blkif_deschedule(blkif_t *blkif)
index 209cd6b1013d73707a47aa83da7bd22f7233b85e..eec15e386447d87b7b70e8e6f3e41f2663ee5c3b 100644 (file)
@@ -84,7 +84,7 @@ static inline void ADD_ID_TO_FREELIST(
 static inline void flush_requests(struct blkfront_info *info)
 {
        RING_PUSH_REQUESTS(&info->ring);
-       notify_via_evtchn(info->evtchn);
+       notify_remote_via_irq(info->irq);
 }
 
 static void kick_pending_request_queues(struct blkfront_info *info)
index 7339ce805edac0617edc9b7d4370e0b82aa67ac4..748dcdd2c0af7d0e834d75bdaf91cfe832b4c1ad 100644 (file)
@@ -842,7 +842,7 @@ static void make_response(blkif_t *blkif, unsigned long id,
        spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
 
        /* Kick the relevant domain. */
-       notify_via_evtchn(blkif->evtchn);
+       notify_remote_via_irq(blkif->irq);
 }
 
 static struct miscdevice blktap_miscdev = {
index 2402a76ea4e122c2284fd4c0671a672686ebeff7..c74b045db2ec710252bf031e5d4a6073fbf60064 100644 (file)
@@ -46,7 +46,8 @@ static inline struct ring_head *inring(void)
 
 
 /* don't block -  write as much as possible and return */
-static int __xencons_ring_send(struct ring_head *ring, const char *data, unsigned len)
+static int __xencons_ring_send(
+       struct ring_head *ring, const char *data, unsigned len)
 {
        int copied = 0;
 
@@ -63,13 +64,9 @@ static int __xencons_ring_send(struct ring_head *ring, const char *data, unsigne
 
 int xencons_ring_send(const char *data, unsigned len)
 {
-       struct ring_head *out = outring();
-       int sent = 0;
-       
-       sent = __xencons_ring_send(out, data, len);
-       notify_via_evtchn(xen_start_info->console_evtchn);
+       int sent = __xencons_ring_send(outring(), data, len);
+       notify_remote_via_irq(xencons_irq);
        return sent;
-
 }      
 
 
index 3170303e8bb33975727ee78559f6e6fe9edd2b63..a4f9c447d202882e101e62d576ee337f6046d384 100644 (file)
@@ -42,7 +42,7 @@ static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE*2+1];
 static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE];
 
 static gnttab_transfer_t grant_rx_op[MAX_PENDING_REQS];
-static unsigned char rx_notify[NR_EVENT_CHANNELS];
+static unsigned char rx_notify[NR_IRQS];
 
 /* Don't currently gate addition of an interface to the tx scheduling list. */
 #define tx_work_exists(_if) (1)
@@ -209,7 +209,7 @@ static void net_rx_action(unsigned long unused)
 {
        netif_t *netif = NULL; 
        s8 status;
-       u16 size, id, evtchn;
+       u16 size, id, irq;
        multicall_entry_t *mcl;
        mmu_update_t *mmu;
        gnttab_transfer_t *gop;
@@ -320,16 +320,16 @@ static void net_rx_action(unsigned long unused)
                                gop->status, netif->domid);
                        /* XXX SMH: should free 'old_mfn' here */
                        status = NETIF_RSP_ERROR; 
-               } 
-               evtchn = netif->evtchn;
+               }
+               irq = netif->irq;
                id = netif->rx->ring[
                        MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id;
                if (make_rx_response(netif, id, status,
                                     (unsigned long)skb->data & ~PAGE_MASK,
                                     size, skb->proto_csum_valid) &&
-                   (rx_notify[evtchn] == 0)) {
-                       rx_notify[evtchn] = 1;
-                       notify_list[notify_nr++] = evtchn;
+                   (rx_notify[irq] == 0)) {
+                       rx_notify[irq] = 1;
+                       notify_list[notify_nr++] = irq;
                }
 
                netif_put(netif);
@@ -339,9 +339,9 @@ static void net_rx_action(unsigned long unused)
        }
 
        while (notify_nr != 0) {
-               evtchn = notify_list[--notify_nr];
-               rx_notify[evtchn] = 0;
-               notify_via_evtchn(evtchn);
+               irq = notify_list[--notify_nr];
+               rx_notify[irq] = 0;
+               notify_remote_via_irq(irq);
        }
 
        /* More work to do? */
@@ -717,7 +717,7 @@ static void make_tx_response(netif_t *netif,
 
        mb(); /* Update producer before checking event threshold. */
        if (i == netif->tx->event)
-               notify_via_evtchn(netif->evtchn);
+               notify_remote_via_irq(netif->irq);
 }
 
 static int make_rx_response(netif_t *netif, 
index abb4524dca6c3674e44dbbb9ca2c8b96961cdc30..132f0026f46f4e2c2ac8523c73d498a020175d3c 100644 (file)
@@ -457,7 +457,7 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* Only notify Xen if we really have to. */
        mb();
        if (np->tx->TX_TEST_IDX == i)
-               notify_via_evtchn(np->evtchn);
+               notify_remote_via_irq(np->irq);
 
        return 0;
 
@@ -776,7 +776,7 @@ static void network_connect(struct net_device *dev)
         */
        np->backend_state = BEST_CONNECTED;
        wmb();
-       notify_via_evtchn(np->evtchn);  
+       notify_remote_via_irq(np->irq);
        network_tx_buf_gc(dev);
 
        if (np->user_state == UST_OPEN)
index 17726f8989925d73cdc331035c2ce47d3dcc5818..0fe22a43f24e3a607be1dbad07eaf246d4e8de74 100644 (file)
@@ -308,7 +308,7 @@ _packet_write(struct packet *pak,
        rc = offset;
        DPRINTK("Notifying frontend via event channel %d\n",
                tpmif->evtchn);
-       notify_via_evtchn(tpmif->evtchn);
+       notify_remote_via_irq(tpmif->irq);
 
        return rc;
 }
index 516aae330d7a5a8ae9358b54db5f8b1835d7fcb1..dadb86656879f7ce9cfbf1211cb27eab12db01e7 100644 (file)
@@ -682,7 +682,7 @@ tpm_xmit(struct tpm_private *tp,
        DPRINTK("Notifying backend via event channel %d\n",
                tp->evtchn);
 
-       notify_via_evtchn(tp->evtchn);
+       notify_remote_via_irq(tp->irq);
 
        spin_unlock_irq(&tp->tx_lock);
        return offset;
index 972236d285d4a1880038bfe7a8816354d42f1089..7c9d8f6ec20e6759f14afd9ee6a8308b4d369397 100644 (file)
@@ -147,7 +147,7 @@ int xb_write(const void *data, unsigned len)
                data += avail;
                len -= avail;
                update_output_chunk(out, avail);
-               notify_via_evtchn(xen_start_info->store_evtchn);
+               notify_remote_via_irq(xenbus_irq);
        } while (len != 0);
 
        return 0;
@@ -192,7 +192,7 @@ int xb_read(void *data, unsigned len)
                pr_debug("Finished read of %i bytes (%i to go)\n", avail, len);
                /* If it was full, tell them we've taken some. */
                if (was_full)
-                       notify_via_evtchn(xen_start_info->store_evtchn);
+                       notify_remote_via_irq(xenbus_irq);
        }
 
        /* If we left something, wake watch thread to deal with it. */
index 360388fec6b597c64ed9ec23a4c80508f5dee47b..d2f5279be89a772b1e220af07ed685c7fb4fa664 100644 (file)
@@ -75,6 +75,12 @@ extern int  bind_evtchn_to_irqhandler(
        void *dev_id);
 extern void unbind_evtchn_from_irqhandler(unsigned int irq, void *dev_id);
 
+/*
+ * Unlike notify_remote_via_evtchn(), this is safe to use across
+ * save/restore. Notifications on a broken connection are silently dropped.
+ */
+void notify_remote_via_irq(int irq);
+
 extern void irq_resume(void);
 
 /* Entry point for notifications into Linux subsystems. */
@@ -115,12 +121,12 @@ static inline void clear_evtchn(int port)
        synch_clear_bit(port, &s->evtchn_pending[0]);
 }
 
-static inline int notify_via_evtchn(int port)
+static inline void notify_remote_via_evtchn(int port)
 {
        evtchn_op_t op;
        op.cmd = EVTCHNOP_send;
        op.u.send.local_port = port;
-       return HYPERVISOR_event_channel_op(&op);
+       (void)HYPERVISOR_event_channel_op(&op);
 }
 
 /*